package cn.uyunsky.platform.service.impl;

import cn.uyunsky.platform.config.bean.menu.PlModule;
import cn.uyunsky.platform.config.bean.menu.PlTran;
import cn.uyunsky.platform.config.bean.menu.PlTree;
import cn.uyunsky.platform.config.reader.MenuReader;
import cn.uyunsky.platform.data.UData;
import cn.uyunsky.platform.data.UDataTool;
import cn.uyunsky.platform.entity.impl.PlRole;
import cn.uyunsky.platform.exception.PLException;
import cn.uyunsky.platform.service.IServiceAbstract;
import cn.uyunsky.platform.util.PL;
import cn.uyunsky.platform.vo.TreeVO;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 描述: 功能树菜单.菜单目录结构
 * 根据平台配置文件数据结构,从配置工厂获取全部TRAN。然后根据角色定义的TRAN过滤，形成本角色对应的TRAN树列表;
 * 其中的TREEVO满足 zTree格式要求
 * User: baiyh
 * Date: 13-7-6
 * Time: 下午5:28
 */
@Service(value = "PLTranService")
@Transactional
public class PLTranService extends IServiceAbstract {

    private static class OPTYPE {
        public static final String GET = "GET";//根据roleid 获取tran列表树
        public static final String UPD = "UPD";//更新roleid 的tran列表树
    }

    private HibernateTemplate hibernateTemplate;

    public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
        this.hibernateTemplate = hibernateTemplate;
    }

    @Override
    public UData doService(UData data) throws PLException {

        String optype = (String) data.getBody().get("optype");

        if (OPTYPE.GET.equals(optype)) {
            return this.getRoleTran(data);
        } else if (OPTYPE.UPD.equals(optype)) {
            return this.updRoleTran(data);
        } else {
            throw new PLException("9999");
        }
    }

    private UData updRoleTran(UData data) {
        String roleId = (String) data.getBody().get("roleid");
        List trans = (List) data.getBody().get("trans");
        PlRole role = hibernateTemplate.get(PlRole.class, roleId);
        if (role.getFlag().equals("0")) {//普通用户才维护角色树列表
            Set trancodes = new HashSet();
            trancodes.addAll(trans);
            role.setTrancode(trancodes);
        }

        return UDataTool.createResult(true);
    }

    private UData getRoleTran(UData data) {
        String roleId = (String) data.getBody().get("roleid");
        List<TreeVO> trees = new ArrayList<TreeVO>();

        MenuReader menuReader = this.getReader(MenuReader.class);
        Set<String> roleTranCodes = new HashSet<String>();
        //boolean ifSysAdmin = false; //前段自己处理
        if (!PL.isEmpty(roleId)) {
            //根据角色获取指定tran
            logger.debug("查询role[" + roleId + "]的所对应交易");
            PlRole role = hibernateTemplate.get(PlRole.class, roleId);
            roleTranCodes = role.getTrancode();
        }

        Map<String, PlTree> allTree = menuReader.getAllTree();
        PlTree tree = allTree.get("menu");//本系统目前仅一组tran的树

        // 将树下的tran先添加进来,相当于展开开始节点后出现的交易列表,
        TreeVO baseMenuNode = new TreeVO();
        baseMenuNode.setId(tree.getId());
        baseMenuNode.setName(tree.getTreename());
        baseMenuNode.setOpen(true);
        baseMenuNode.setParent(true);
        baseMenuNode.setNocheck(true);


        //目前规则下总模块下没有TRAN,都是第一级module
        Set<PlTran> treeTrans = tree.getTrans();
        addVOChildrenByTrans( baseMenuNode, treeTrans, roleTranCodes);

        // 将树下的module添加进来 相当于展开开始节点后出现的模块,即leaf=false
        Set<PlModule> treeModule = tree.getModules();
        for (PlModule module : treeModule) {
            baseMenuNode.addChildren(getVOByModule(module, roleTranCodes));
        }

        trees.add(baseMenuNode);//目前仅一个menu树;
        return UDataTool.createOneUData("menu", trees);
    }

    private TreeVO getVOByModule(PlModule module, Set<String> roletrans) {
        // 先是一个树枝节点
        TreeVO aModuleNode = new TreeVO();
        aModuleNode.setId(module.getId());
        aModuleNode.setName(module.getText());
        aModuleNode.setOpen(true);
        aModuleNode.setParent(true);
        aModuleNode.setNocheck(true);
        // 添加叶子节点
        addVOChildrenByTrans(aModuleNode, module.getTrans(), roletrans);

        // 添加孩子树枝节点
        Set<PlModule> children = module.getChildren();
        for (PlModule aChildren : children) {
            TreeVO vo2 = getVOByModule( aChildren, roletrans);
            aModuleNode.addChildren(vo2);
        }
        return aModuleNode;
    }

    private void addVOChildrenByTrans(TreeVO vo, Set<PlTran> trans, Set<String> roleTrans) {
        for (PlTran tran : trans) {
            TreeVO vo2 = new TreeVO();
            vo2.setId(tran.getCode());
            vo2.setName(tran.getText());
            vo2.setOpen(true);
            // 角色包含勾选,否则不勾选
            if (roleTrans.contains(tran.getCode())) {
                vo2.setChecked(true);
            } else {
                vo2.setChecked(false);
            }
            vo.addChildren(vo2);
        }
    }


}
